#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSizePolicy>
#include <QDateTime>
#include "src/utils/log.h"
#include "src/common/localsetting.h"
#include "src/common/batteryinfo.h"
#include "src/common/xwindowmanager.h"
#include "src/baseui/systemrebootdialog.h"
#include "src/baseui/messagetoast.h"

#include <QProcess>
#include <QCamera>
#include <QCameraInfo>

#define  MAX_FACE_RETRY_COUNT 3


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_arrowWidget(nullptr)
    , m_faceArrowWidget(nullptr)
{

    qRegisterMetaType<Loginlogical::Login_Result>("Loginlogical::Login_Result");
    qRegisterMetaType<Loginlogical::Face_Regist_Result>("Loginlogical::Face_Regist_Result");
    qRegisterMetaType<Loginlogical::Face_Predict_Result>("Loginlogical::Face_Predict_Result");

    ui->setupUi(this);

    setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
    setWindowState(Qt::WindowFullScreen | Qt::WindowActive);

    connect(ui->pushButton_help, &QPushButton::clicked, this, &MainWindow::onShowhelpClicked);
    connect(ui->pushButton_keyboard, &QPushButton::clicked, this, &MainWindow::onKeyboardClicked);
    connect(ui->pushButton_battery, &QPushButton::clicked, this, &MainWindow::onBatteryClicked);
    connect(ui->pushButton_reboot, &QPushButton::clicked, this, &MainWindow::onSystemrebootClicked);

    connect(ui->widget_input, &KeyinputWidget::sigKeyEnter, this, &MainWindow::onLoginEnter);
    connect(&m_loginlogical, &Loginlogical::sigLoginResult, this, &MainWindow::onLoginResult);
    connect(&m_retryTimer, &QTimer::timeout, this, &MainWindow::onPasswdLockerTimeout);

    connect(ui->pushButton_face, &QPushButton::clicked, this, &MainWindow::onFaceAuthClicked);
    connect(&m_loginlogical, &Loginlogical::sigFacePredictResult, this, &MainWindow::onFaceAuthResult);

    initDateTime();
    initUserName();
    initToolButtons();

    if (!LocalSetting::instance()->getFaceAuthUsed())
    {
        ui->pushButton_face->setVisible(false);
    }
    else
    {
        if (m_loginlogical.getRegistedFaceLabels().empty())
            ui->pushButton_face->setVisible(false);

//        if (QCameraInfo::availableCameras().size() <= 0)
//            ui->pushButton_face->setVisible(false);
    }

    ui->pushButton_help->setVisible(false);
    ui->widget_faceanimation->setVisible(false);


    m_updateTimer.setInterval(5000);
    m_updateTimer.start();
    connect(&m_updateTimer, &QTimer::timeout,  [&](){
        QDateTime curr = QDateTime::currentDateTime();
        QString datetext = curr.toString("MM月dd日 dddd");// + QString(locale.toString(QDateTime::currentDateTime(),QString("dddd")));
        QString timetext = curr.toString("hh:mm");
        ui->label_date->setText(datetext);
        ui->label_time->setText(timetext);

        BatteryInfo::Battery_State state = BatteryInfo::Battery_Discharging;
        quint32 percent = 100;
        BatteryInfo::queryBatteryInfo(state, percent);

//        state = BatteryInfo::Battery_Discharging;
//        percent = 23;
        ui->widget_battery->setValue((int)percent);
        ui->widget_battery->setIsCharging(state == BatteryInfo::Battery_Charging);
    });

    // init lock and retry time
    quint32 failedCount = m_loginlogical.getCanRetryCount();
    quint32 retrytimedelay = m_loginlogical.getLockRetryTimedelay();
    INFO("retry delay time : " << retrytimedelay);
    if (retrytimedelay > 0)
    {
        startRetrylockTimer();
        ui->widget_input->setKeyinputLocked(true);
        ui->pushButton_help->setVisible(true);

        ui->pushButton_face->setEnabled(false);
    }
    else
    {
        ui->widget_input->setKeyinputLocked(false);
        if (failedCount > 0)
            ui->label_message->setText(QString("继续输错%1次将锁定账户").arg(5-failedCount));
        else
            ui->label_message->clear();
    }

    m_faceRetryCount = LocalSetting::instance()->getLastFaceauthFailedCount();
    if (m_faceRetryCount >= MAX_FACE_RETRY_COUNT)
        ui->pushButton_face->setEnabled(false);

    ui->pushButton_face->installEventFilter(this);

    initSystemEnv();
    QTimer::singleShot(1000, this, [](){QProcess::startDetached("killall /usr/bin/kglobalaccel5");});
}

MainWindow::~MainWindow()
{
    restoreSystemEnv();
    delete ui;
}

void MainWindow::initSystemEnv()
{
#ifndef _WIN32
    XWindowManager::disableSystemCloseActive();
    XWindowManager::hideSystemTaskbar();
    XWindowManager::disableSystemWin();
    XWindowManager::disableSystemCloseActive();

    //    if (misFirstStartup)
    XWindowManager::exitGreeterProgram();
#endif
}

void MainWindow::restoreSystemEnv()
{
#ifndef _WIN32
    XWindowManager::enableSystemScreenSleepactive();
    XWindowManager::showSystemTaskbar();
    XWindowManager::closeSystemConfigBlocked();
    XWindowManager::enableSystemWin();
#endif
}


void MainWindow::initDateTime()
{
//    QLocale locale = QLocale::Chinese;
    QDateTime curr = QDateTime::currentDateTime();
    QString datetext = curr.toString("MM月dd日 dddd");// + QString(locale.toString(QDateTime::currentDateTime(),QString("dddd")));
    QString timetext = curr.toString("hh:mm");
    ui->label_date->setText(datetext);
    ui->label_time->setText(timetext);
}
void MainWindow::initUserName()
{
    ui->label_name->setText(Loginlogical::getSystemUsername());
}
void MainWindow::initToolButtons()
{
    ui->pushButton_battery->setVisible(false);
    ui->widget_battery->setBgRadius(2);
    ui->widget_battery->setBorderRadius(2);
    ui->widget_battery->setHeadRadius(1);
    ui->widget_battery->setBorderWidth(2);
    ui->widget_battery->setBorderColorStart(QColor(255,255,255));
    ui->widget_battery->setBorderColorEnd(QColor(255,255,255));
    ui->widget_battery->setNormalColorStart(QColor(255,255,255));
    ui->widget_battery->setNormalColorEnd(QColor(255,255,255));
    ui->widget_battery->setChargingColorStart(QColor(0,213,85));
    ui->widget_battery->setChargingColorEnd(QColor(0,213,85));
    ui->widget_battery->setAnimation(false);
    ui->widget_battery->setAlarmValue(20);

    BatteryInfo::Battery_State state = BatteryInfo::Battery_Discharging;
    quint32 percent = 100;
    BatteryInfo::queryBatteryInfo(state, percent);
    ui->widget_battery->setValue((int)percent);
    ui->widget_battery->setIsCharging(state == BatteryInfo::Battery_Charging);
}

void MainWindow::startRetrylockTimer()
{
    m_retryTimer.setInterval(1000);
    m_retryTimer.start();

}

void MainWindow::onPasswdLockerTimeout()
{
    quint32 lockSeconds = m_loginlogical.getLockRetryTimedelay();

    if (lockSeconds == 0)
    {
        ui->widget_input->setKeyinputLocked(false);
        ui->label_message->clear();
        m_retryTimer.stop();

        ui->pushButton_face->setEnabled(m_faceRetryCount < MAX_FACE_RETRY_COUNT);
        return;
    }

    QString errMsg = QString("账户已锁定，请%1后再尝试").arg(m_loginlogical.getSecondsString(lockSeconds));
    ui->label_message->setText(errMsg);

    m_retryTimer.setInterval((lockSeconds >= 120) ? 30000 : 1000);

}

void MainWindow::onFaceAuthResult(Loginlogical::Face_Predict_Result result)
{
    INFO("face auth result " << result);
    ui->widget_4->setEnabled(true);
    ui->widget_faceanimation->stopEyeBlinkAnimation();

    m_loginlogical.stopThreadCapturing();

    if (result == Loginlogical::Face_Predict_Success)
    {
        ui->widget_faceanimation->startMouthSmellAnimation();

        LocalSetting::instance()->removeLastloginDatetimeCount();
        LocalSetting::instance()->removeLastFaceauthDatetimeCount();
        INFO("face auth success, login!")
        QTimer::singleShot(1500, [](){
            qApp->exit();
        });
    }
    else if (result == Loginlogical::Face_Predict_Failed_Nocamera)
    {
        INFO("face auth failed, nocamera!")
        ui->widget_6->setVisible(true);
        ui->widget_faceanimation->setVisible(false);
    }
    else if (result == Loginlogical::Face_Predict_Failed_Timeout)
    {
        INFO("face auth failed, timeout!")
        ui->widget_6->setVisible(true);
        ui->widget_faceanimation->setVisible(false);
    }
    else if (result == Loginlogical::Face_Predict_Failed_Noface || result == Loginlogical::Face_Predict_Failed_Unknownface)
    {
        INFO("face auth failed, not detected!")
        ui->widget_6->setVisible(true);
        ui->widget_faceanimation->setVisible(false);
    }

    if (result != Loginlogical::Face_Predict_Success)
    {
        m_faceRetryCount++;
        LocalSetting::instance()->setLastFaceauthFailedCount(m_faceRetryCount);
        if (m_faceRetryCount >= MAX_FACE_RETRY_COUNT)
        {
            ui->label_message->setText("面容已锁定，输入密码解锁电脑");
            ui->pushButton_face->setEnabled(false);
        }
        else
        {
            ui->pushButton_face->setEnabled(true);
        }
    }
}

void MainWindow::onFaceAuthClicked()
{
    if (QCameraInfo::availableCameras().size() <= 0)
    {
        MessageToast::instance().show(MessageToast::ERROR, "请检查摄像头设备是否正常！");
        return;
    }

    ui->widget_6->setVisible(false);
    ui->widget_faceanimation->setVisible(true);

    ui->widget_faceanimation->startEyeBlinkAnimation();
//    ui->widget_faceanimation->startMouthSmellAnimation();

    ui->pushButton_face->setEnabled(false);

    QCameraInfo info = QCameraInfo::defaultCamera();
    m_loginlogical.facePredictThread(0); // info.deviceName());

    ui->widget_4->setEnabled(false);
}

void MainWindow::onLoginResult(Loginlogical::Login_Result res, const QString& resultMsg)
{

    if (res == Loginlogical::Login_Success)
    {
        INFO("login success");
        LocalSetting::instance()->removeLastFaceauthDatetimeCount();
        LocalSetting::instance()->removeLastloginDatetimeCount();
        qApp->exit();
    }
    else if (res == Loginlogical::Login_Failed_AcctpwdError)
    {
        INFO("login failed pwd error");
        quint32 count = m_loginlogical.getCanRetryCount();
        quint32 retrytimedelay = m_loginlogical.getLockRetryTimedelay();

        QString errMsg;
        if (count <= 4 || retrytimedelay == 0)
        {
            errMsg = QString("认证失败，继续输错%1次将锁定账户").arg(5-count);
            ui->widget_input->setKeyinputLocked(false);
            ui->widget_input->clearKeyinputString();
        }
        else
        {
            errMsg = QString("账户已锁定，请%1后再尝试").arg(m_loginlogical.getSecondsString(retrytimedelay));
            ui->widget_input->setKeyinputLocked(true);
            startRetrylockTimer();
            ui->pushButton_help->setVisible(true);

            ui->pushButton_face->setEnabled(false);
        }
        qDebug() << "errMsg " << count << retrytimedelay;
        ui->label_message->setText(errMsg);
    }
    else if (res == Loginlogical::Login_Failed_Locked)
    {
        INFO("login failed locked");
    }
}

void MainWindow::onLoginEnter(const QString& passwd)
{
    qDebug() << "onLoginEnter";
    QString resultString;
//    Loginlogical::Login_Result res = m_loginlogical.login(ui->label_name->text(), passwd, resultString);

    ui->label_message->clear();
    ui->widget_input->setKeyinputLocked(true);
    m_loginlogical.loginThread(ui->label_name->text(), passwd);
}

void MainWindow::setFacelockArrowwidgetVisible(bool visible)
{
    if (m_faceArrowWidget == nullptr)
    {
        m_faceArrowWidget = new ArrowWidget(this);
        QLabel* centerText = new QLabel(this);
        centerText->setText("面容已锁定");
        centerText->setFixedSize(70, 22);
        centerText->setStyleSheet(
            "QLabel{"
            "    font-family: Source Han Sans CN;"
            "    font-size: 14px;"
            "    font-weight: 400;"
            "    line-height: 21px;"
            "    text-align: center;"
            "    background-color: transparent;"
            "    color: rgba(38,38,38,1);}"
            );

        m_faceArrowWidget->setCenterWidget(centerText);
        m_faceArrowWidget->setStartPos(52);
        m_faceArrowWidget->setTriangleInfo(20, 10);
        m_faceArrowWidget->setFixedSize(122, 83);
        // @todo UpdateLayeredWindowIndirect failed for ptDst ??
        m_faceArrowWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::NoDropShadowWindowHint);
    }

    if (visible)
    {
        m_faceArrowWidget->move(ui->pushButton_face->mapTo(this, QPoint(-28, 58)));
        m_faceArrowWidget->show();
    }
    else
    {
        m_faceArrowWidget->hide();
    }

}

void MainWindow::onShowhelpClicked()
{
    qDebug() << "onShowhelpClicked";

    if (m_arrowWidget == nullptr)
    {
        m_arrowWidget = new ArrowWidget(this);
        QLabel* centerText = new QLabel(this);
        centerText->setText("如果忘记密码，你可以拨打服务热线：400-089-1870");
        centerText->setFixedSize(327, 21);
        centerText->setStyleSheet(
            "QLabel{"
            "    font-family: Source Han Sans CN;"
            "    font-size: 14px;"
            "    font-weight: 400;"
            "    line-height: 21px;"
            "    text-align: center;"
            "    background-color: transparent;"
            "    color: rgba(38,38,38,1);}"
            );

        m_arrowWidget->setCenterWidget(centerText);
        m_arrowWidget->setStartPos(46);
        m_arrowWidget->setTriangleInfo(20, 10);
        m_arrowWidget->setFixedSize(389, 93);
        // @todo UpdateLayeredWindowIndirect failed for ptDst ??
        m_arrowWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::Popup | Qt::NoDropShadowWindowHint);
    }
    m_arrowWidget->move(ui->pushButton_help->mapTo(this, QPoint(-39, 30)));
    m_arrowWidget->show();
}

void MainWindow::onKeyboardClicked()
{

}

void MainWindow::onBatteryClicked()
{

}

void MainWindow::onSystemrebootClicked()
{
//    static bool isLocked = false;
//    ui->widget_input->setKeyinputLocked(isLocked);
//    isLocked = !isLocked;
//    qApp->exit();

//    XWindowManager::showSystemReboot();
    SystemRebootDialog* dlg = new SystemRebootDialog(this);
    dlg->setModal(true);
    dlg->showFullScreen();
    dlg->exec();

    dlg->deleteLater();
}

bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
//    if (watched == ui->pushButton_help)
//    {
//        qDebug() << "MainWindow::eventFilter pushButton_help" << event->type();
//        if (event->type() == QEvent::Enter)
//        {
//            m_arrowWidget->setText("xsadsadsad");//"如果忘记密码，你可以拨打服务热线：400-089-1870");
//            m_arrowWidget->setDerection(ArrowWidget::up);
//            m_arrowWidget->setStartPos(46);
//            m_arrowWidget->setTriangleInfo(20, 10);
//            m_arrowWidget->setFixedSize(359, 53);

//            m_arrowWidget->move(ui->pushButton_help->mapTo(this, QPoint(-67, 40)));
//            m_arrowWidget->show();
//        }
//        else if (event->type() == QEvent::Leave)
//        {
//            m_arrowWidget->hide();
//        }
//        return QObject::eventFilter(watched, event);
//    }
//    if (watched == m_arrowWidget)
//    {
//        qDebug() << "MainWindow::eventFilter m_arrowWidget" << event->type();
//        if (event->type() == QEvent::WindowDeactivate)
//        {
//            m_arrowWidget->setVisible(false);
//            return true;
//        }
//    }

    if (watched == ui->pushButton_face)
    {
        if (event->type() == QEvent::HoverEnter)
        {
//            qDebug() << "MainWindow::eventFilter pushButton_face HoverEnter" << event->type();
            if (m_faceRetryCount >= MAX_FACE_RETRY_COUNT)
                setFacelockArrowwidgetVisible(true);

            return true;
        }
        if (event->type() == QEvent::HoverLeave)
        {
//            qDebug() << "MainWindow::eventFilter pushButton_face HoverLeave" << event->type();
            if (m_faceRetryCount >= MAX_FACE_RETRY_COUNT)
                setFacelockArrowwidgetVisible(false);

            return true;
        }
    }

    return QMainWindow::eventFilter(watched, event);
}

